﻿using System;
using System.Collections.Generic;
using System.Device.Location;
using System.Diagnostics;
using System.Globalization;
using System.IO;

namespace GPXCleaner
{
  class Airports : SortedList<double, Airport>, IDisposable
  {
    private int _maxCount;
    private bool _useSmallAirports;
    private GeoCoordinateWatcher _watcher;
    private double _lat;
    private double _lon;

    public Airports(int maxCount, bool useSmallAirports)
    {
      _maxCount = maxCount;
      _useSmallAirports = useSmallAirports;
      _watcher = new GeoCoordinateWatcher();
      _watcher.PositionChanged += Watcher_PositionChanged;
      _watcher.Start();
    }
    public void Dispose()
    {
      ((IDisposable)_watcher).Dispose();
    }

    public event EventHandler<EventArgs> Ready = delegate { };

    public List<GPX10.gpxWpt> WayPoints
    {
      get
      {
        List<GPX10.gpxWpt> lst = new List<GPX10.gpxWpt>();
        for (int i = 0; i < _maxCount && i < Count; i++)
        {
          GPX10.gpxWpt wp = new GPX10.gpxWpt();
          Airport air = this[this.Keys[i]];
          wp.name = air.Iata;
          wp.desc = air.Name;
          wp.lat = (decimal)air.Latitude;
          wp.lon = (decimal)air.Longitude;
          wp.ele = (decimal)air.Elevation;
          wp.eleSpecified = true;
          lst.Add(wp);
        }
        return lst;
      }
    }

    private void Watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
    {
      GeoCoordinate coord = e.Position.Location;
      if (!coord.IsUnknown)
      {
        GeoCoordinateWatcher watcher = sender as GeoCoordinateWatcher;
        watcher.Stop();
        _lat = coord.Latitude;
        _lon = coord.Longitude;
        ReadAirports();
      }
    }

    private void ReadAirports()
    {
      Clear();
      Add(0.0, new Airport("Home Location", "000", _lat, _lon, 0.0));
      using (StreamReader file = new StreamReader("Airports.csv"))
      {
        string line;
        while ((line = file.ReadLine()) != null)
        {
          string[] parts = line.Split(new char[] { ',' });
          if (parts[2].Trim(new char[] { '\"' }).Equals("large_airport", StringComparison.OrdinalIgnoreCase) ||
             (_useSmallAirports && parts[2].Trim(new char[] { '\"' }).Equals("small_airport", StringComparison.OrdinalIgnoreCase)))
          {
            try
            {
              string name = parts[3].Trim(new char[] { '\"' });
              string iata = parts[13].Trim(new char[] { '\"' });
              double lat = Double.Parse(parts[4], CultureInfo.InvariantCulture);
              double lon = Double.Parse(parts[5], CultureInfo.InvariantCulture);
              double ele = String.IsNullOrEmpty(parts[6]) ? 0 : Double.Parse(parts[6], CultureInfo.InvariantCulture);
              double distance = Math.Sqrt(Math.Pow(_lat - lat, 2) + Math.Pow(_lon - lon, 2));
              if (!string.IsNullOrEmpty(iata))
              {
                Add(distance, new Airport(name, iata, lat, lon, ele));
              }
            }
            catch (FormatException)
            {
              Trace.WriteLine(line);
            }
            catch (ArgumentException)
            {
              Trace.WriteLine(line);
            }
          }
        }
      }
      Ready.Invoke(this, new EventArgs());
    }
  }
}
